package cn.zyq.demo.system.aspect;

import cn.zyq.demo.system.common.BackParam;
import cn.zyq.demo.system.common.BaseBean;
import cn.zyq.demo.system.common.PageParam;
import cn.zyq.demo.system.config.consts.system.SystemConfig;
import cn.zyq.demo.system.enums.core.ResponseCodeEnum;
import cn.zyq.demo.system.exception.BusinessException;
import cn.zyq.demo.system.ry.util.IpUtils;
import cn.zyq.demo.system.ry.util.ServletUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

@Aspect
@Component
@Slf4j
public class ControllerAspect {
    // @Pointcut("execution(public * cn.zyq.demo.controller.mgt..*(..))"
    //         + " || execution(public * cn.zyq.demo.controller.h5..*(..))")
    // private void controllerAspect() {
    // }

    @Pointcut("execution(public * cn.zyq.demo.controller..*(..))"
            + " && !execution(public * cn.zyq.demo.controller.mgt.login..*(..))"
            + " && !execution(public * cn.zyq.demo.controller.file..*(..))"
            + " && !execution(public * cn.zyq.demo.controller.wx..*(..))")
    private void controllerAspect() {
    }

    @Around(value = "controllerAspect()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        HttpServletRequest request = ServletUtils.getRequest();

        String id = UUID.randomUUID().toString();
        long startTime = System.currentTimeMillis();//开始时间
        this.paramsLog(pjp, id);//打印请求信息
        Object result = pjp.proceed();
        if (result == null) {
            throw new BusinessException(ResponseCodeEnum.SUCCESS);
        }
        BackParam backParam = new BackParam();
        backParam.setMsg(ResponseCodeEnum.SUCCESS.getMsg());
        backParam.setCode(ResponseCodeEnum.SUCCESS.getCode());
        backParam.setData(result);
        this.resultLog(backParam, id, startTime);//答应返回结果
        return backParam;
    }

    private void paramsLog(ProceedingJoinPoint pjp, String id) {
        HttpServletRequest request = ServletUtils.getRequest();
        String ip = IpUtils.getIpAddr();
        StringBuffer buffer = new StringBuffer();
        buffer.append("\n\n==========================").append(id).append("请求开始===================================");
        buffer.append("\n\t会话编号：").append(request.getRequestedSessionId());
        buffer.append("\n\t请求接口：").append(request.getRequestURI());
        buffer.append("\n\t请求IP：").append(ip);
        buffer.append("\n\t自定义请求Id：").append(id);
        if (!SystemConfig.env.equals("prod")) {
            //非生产环境环境，打开参数监控
            Object[] args = pjp.getArgs();
            for (int i = 0; i < args.length; i++) {
                Object arg = args[i];
                if (arg instanceof BaseBean || arg instanceof PageParam) {
                    buffer.append("\n\t请求参数").append(i).append("：").append(JSON.toJSONString(arg));
                }
            }
        }
        buffer.append("\n\n==========================").append(id).append("请求开始===================================");
        log.debug(buffer.toString());
    }

    private void resultLog(BackParam backParam, String id, long startTime) {
        long endTime = System.currentTimeMillis();//结束时间
        HttpServletRequest request = ServletUtils.getRequest();
        StringBuffer resultBuffer = new StringBuffer();
        resultBuffer.append("\n\n==========================").append(id).append("请求结束===================================");
        resultBuffer.append("\n\t返回状态：").append(backParam.getCode());
        resultBuffer.append("\n\t请求接口：").append(request.getRequestURI());
        if (!SystemConfig.env.equals("prod")) {
            //非生产环境环境，打开参数监控
            resultBuffer.append("\n\t返回数据：").append(JSON.toJSONString(backParam.getData()));
        }
        resultBuffer.append("\n\t请求耗时：").append(endTime - startTime).append("毫秒");
        resultBuffer.append("\n\n==========================").append(id).append("请求结束===================================");
        log.debug(resultBuffer.toString());
    }
}
